#include "inoise.fxh"

float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 WorldInverseTranspose;

float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.0;

float3 DiffuseLightDirection = float3(1, 1, 0);
float4 DiffuseColor = float4(1, 1, 1, 1);
float DiffuseIntensity = 0.7;

Texture darkTexture;
Texture lightTexture;

int size = 512;
float scale = 4.5;

float freq = 10;

sampler darkSampler = sampler_state 
{ 
    texture = <darkTexture>; 
    magfilter = LINEAR; 
    minfilter = LINEAR; 
    mipfilter = LINEAR; 
};

sampler lightSampler = sampler_state 
{ 
    texture = <lightTexture>; 
    magfilter = LINEAR; 
    minfilter = LINEAR; 
    mipfilter = LINEAR; 
};

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float4 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 Color : COLOR0;
    float3 TexCoord : TEXCOORD0;
};

float4 interpolate(float4 c1, float4 c2, float n)
{
	float4 n4 = {n,n,n,n};
	return lerp(c1, c2, n4);
}

VertexShaderOutput VS_Perlin(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);

    float4 normal = normalize(mul(input.Normal, WorldInverseTranspose));
    float lightIntensity = dot(normal, DiffuseLightDirection);
    output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);
	
    output.TexCoord = input.Position / (size * scale);
    return output;
}

float4 PS_Perlin(VertexShaderOutput input): COLOR
{
	float noise = fBm(input.TexCoord * size * freq, 1)*0.5+0.5;
	float2 coord = {input.TexCoord.x, input.TexCoord.z};
	float4 c1 = tex2D(darkSampler, coord);
	float4 c2 = tex2D(lightSampler, coord);
//float4 c1 = {0.04, 0.35, 0.0, 1.0};
//float4 c2 = {0.08, 0.5, 0.0, 1.0};

	float4 color = interpolate(c1, c2, noise);
	return length(input.Color)*color;
 }

technique fBm
{
    pass p0 
    {
		VertexShader = compile vs_3_0 VS_Perlin();
		PixelShader  = compile ps_3_0 PS_Perlin();
    }
}